package cn.jji8.patternLogin.spigot.login;

import cn.jji8.patternLogin.spigot.data.Data;
import cn.jji8.patternLogin.spigot.PatternLogin;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.*;

import java.util.*;

@SuppressWarnings("unused")
public class LoginManager implements Listener {
    static final Map<Player,LoginMode> playerLoginModeMap = new HashMap<>();
    static final Set<Player> noLoginPlayer = new HashSet<>();
    /**
     * 判断玩家是否登录，登录了true，没登录false
     * */
    public static boolean isLogin(Player player){
        return !noLoginPlayer.contains(player);
    }
    /**
     * 设置某玩家已经登入
     * */
    public static void setLogin(Player player){
        noLoginPlayer.remove(player);
        playerLoginModeMap.remove(player);
        //设置玩家已登录
        Bukkit.getScheduler().runTaskAsynchronously(PatternLogin.getMain(), () -> Data.setPlayerAlreadyLogin(player.getName()));
        //执行登录之后任务
        LoginTask.loginBefore(player);

        Bukkit.getServer().getScheduler().runTask(PatternLogin.getMain(), () -> {
            //让玩家可以看见全部玩家
            for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
                player.showPlayer(PatternLogin.getMain(),onlinePlayer);
            }
        });
    }
    /**
     * 获取玩家应该的LoginMode，需要注册就PlayerReg,需要登入就PlayerLogin
     * */
    public static LoginMode getPlayerShouldLoginMode(Player player){
       String s = Data.getPassword(player.getName());
       if(s==null){
           return new PlayerReg(player);
       }else {
           return new PlayerLogin(player);
       }
    }
    /**
     * 保存在线且已经登入的玩家的数据
     * */
    public static void serveAllPrayerLocation() {
        Collection<? extends Player> OnlinePlayerSet = Bukkit.getServer().getOnlinePlayers();
        for (Object o : OnlinePlayerSet) {
            if(o instanceof Player){
                if(!playerLoginModeMap.containsKey(o)){
                    Data.setLocation(((Player)o).getName(),((Player)o).getLocation());
                }
            }
        }
    }
    /**
     * 设置某玩家需要登录
     * */
    public static void setPlayerNeedLogin(Player player){
        noLoginPlayer.add(player);
        //让玩家看不见全部玩家
        for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
            player.hidePlayer(PatternLogin.getMain(),onlinePlayer);
        }
        //让没登录的玩家看不见他
        for (Player player1 : noLoginPlayer) {
            player1.hidePlayer(PatternLogin.getMain(),player);
        }

        LoginNews.longNews(player,"等待加载..");
        Bukkit.getScheduler().runTaskAsynchronously(PatternLogin.getMain(), () -> {
            Location location = Data.getLocation(player.getName());
            if(location==null){
                Data.setLocation(player.getName(),player.getLocation());
            }
            playerLoginModeMap.put(player,getPlayerShouldLoginMode(player));
            if(Data.getPlayerNeedLogin(player.getName())){
                Bukkit.getScheduler().runTask(PatternLogin.getMain(), () -> player.teleport(new Location(LoginWorld.getLoginWord(),Configuring.playerLoginX+0.5,Configuring.playerLoginY+0.1,Configuring.playerLoginZ+0.5)));
            }else {
                setLogin(player);
            }
        });
        LoginTask.loginAfter(player);
    }
    /**
     * 玩家进入服务器时触发
     * */
    @SuppressWarnings("unused")
    @EventHandler
    public void Listener(PlayerJoinEvent a){
        setPlayerNeedLogin(a.getPlayer());
    }
    /**
     * 玩家离开服务器时触发
     * */
    @SuppressWarnings("unused")
    @EventHandler
    public void Listener(PlayerQuitEvent a){
        if(!isLogin(a.getPlayer())){
            playerLoginModeMap.remove(a.getPlayer());
            noLoginPlayer.remove(a.getPlayer());
            if (Configuring.logician){
                Bukkit.getServer().getScheduler().runTaskAsynchronously(PatternLogin.getMain(),()-> Data.setLocation(a.getPlayer().getName(),a.getPlayer().getLocation()));
            }
           return;
        }
        LoginNews.PlayerLeave(a.getPlayer());
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void WanJiaYiDong(PlayerMoveEvent a){//玩家移动时
        if(!isLogin(a.getPlayer())){
            Location location = new Location(LoginWorld.getLoginWord(),Configuring.playerLoginX+0.5,Configuring.playerLoginY+0.1,Configuring.playerLoginZ+0.5);
            if(!LoginWorld.getLoginWord().equals(a.getPlayer().getLocation().getWorld())){
                a.getPlayer().teleport(location);
                return;
            }
            if(a.getPlayer().getLocation().distance(location)>Configuring.playerR){
                a.getPlayer().teleport(location);
            }
        }
    }
    /**
     * 玩家与方块交互
     * */
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(PlayerInteractEvent a){
        if(isLogin(a.getPlayer())){
            return;
        }
        a.setCancelled(true);
        LoginMode loginMode = playerLoginModeMap.get(a.getPlayer());
        if(loginMode==null){
            return;
        }
        loginMode.RightClick(a);
    }

    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(PlayerDropItemEvent a){//玩家丢物品
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(BlockBreakEvent a){//玩家破坏方块
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(BlockPlaceEvent a){//玩家放置方块
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(PlayerSwapHandItemsEvent a){//玩家切换副手
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(PlayerInteractEntityEvent a){//玩家点击实体时
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(EntityDamageByEntityEvent a){//实体攻击实体
        if(!(a.getEntity() instanceof Player)){
            return;
        }
        if(!isLogin((Player)a.getEntity())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(EntityDamageByBlockEvent a){//实体受到方块伤害
        if(!(a.getEntity() instanceof Player)){
            return;
        }
        if(!isLogin((Player)a.getEntity())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(EntityPickupItemEvent a){//实体捡起物品
        if(!(a.getEntity() instanceof Player)){
            return;
        }
        if(!isLogin((Player)a.getEntity())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(InventoryClickEvent a) {//点击物品栏
        if(!(a.getWhoClicked() instanceof Player)){
            return;
        }
        if(!isLogin((Player)a.getWhoClicked())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(AsyncPlayerChatEvent a) {//聊天
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }
    @SuppressWarnings("unused")
    @EventHandler
    public void monitor(PlayerCommandPreprocessEvent a) {//命令
        if(!isLogin(a.getPlayer())){
            a.setCancelled(true);
        }
    }

}
